package process

import (
	"encoding/json"
	"fmt"
	"go_code/chatroom/common/message"
	"go_code/chatroom/server/model"
	"go_code/chatroom/server/utils"
	"net"
)

type UserProcess struct {
	Conn net.Conn `json:"conn"`
	//那个客户的
	UserId int `json:"userId"`
}

//通知所有在线用户
func (this *UserProcess)NotifyOtherOnlineUser(userId int)  {

	//遍历，一个个发送
	for id, up := range userMgr.onlineUsers{
		//过滤掉自己
		if id == userId {
			continue
		}
		up.NotifyMeOnline(userId)
	}
}

func (this *UserProcess) NotifyMeOnline(userId int)  {
	var mes message.Message
	mes.Type = message.NotifyUserStatusMesType

	var notifyUserStatusMes message.NotifyUserStatusMes
	notifyUserStatusMes.UserId = userId
	notifyUserStatusMes.Status = message.UserOnline

	//序列化
	data, err := json.Marshal(notifyUserStatusMes)
	if err != nil {
		fmt.Println("42 json.Marshal err=", err)
		return
	}
	mes.Data = string(data)

	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("49 json.Marshal err=", err)
		return
	}

	//发送
	//发送数据
	tf := &utils.Transfer{
		Conn: this.Conn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("NotifyMeOnline err", err)
		return
	}
}


//注册
func (this *UserProcess)ServerProcessRegister(mes *message.Message)  {
	//1、先从mes中取出mes.Data，并直接反序列化成loginMes
	var registerMes message.RegisterMes
	//传入地址否则报错
	err := json.Unmarshal([]byte(mes.Data), &registerMes)
	if err != nil {
		fmt.Println("97json.Unmarshal err=", err)
		return
	}

	//声明一个resMes
	var resMes message.Message
	resMes.Type = message.RegisterResMesType

	//声明loginResMes
	var registerResMes message.RegisterResMes
	//到redis数据库中完成验证
	err = model.MyUserDao.Register(&registerMes.User)
	if err != nil {
		if err == model.ERROR_USER_NOTEXISTS {
			registerResMes.Code = 505
			registerResMes.Error = model.ERROR_USER_NOTEXISTS.Error()
		}else {
			registerResMes.Code = 506
			registerResMes.Error = "注册发生未知错误"
		}
	}else {
		registerResMes.Code = 200
	}

	data, err := json.Marshal(registerResMes)
	if err != nil {
		fmt.Println("48 json.Marshal err=", err)
		return
	}

	//将data赋值给resMes
	resMes.Data = string(data)

	//resMes 进行序列化，准备发送
	data, err = json.Marshal(resMes)
	if err != nil {
		fmt.Println("129json.Marsha fail=", err)
		return
	}

	//发送数据
	tf := &utils.Transfer{
		Conn: this.Conn,
	}
	err = tf.WritePkg(data)
	return

}


//专门处理登陆请求
func (this *UserProcess) ServerProcessLogin(mes *message.Message) (err error) {
	//核心代码
	//1、先从mes中取出mes.Data，并直接反序列化成loginMes
	var loginMes message.LoginMes
	//传入地址否则报错
	err = json.Unmarshal([]byte(mes.Data), &loginMes)
	if err != nil {
		fmt.Println("97json.Unmarshal err=", err)
		return
	}

	//声明一个resMes
	var resMes message.Message
	resMes.Type = message.LoginResType

	//声明loginResMes
	var loginResMes message.LoginResMes

/*	//如果用户id=100，密码=asd，认为合法
	if loginMes.UserId == 100 && loginMes.UserPwd == "asd" {
		loginResMes.Code = 200
	}else {
		loginResMes.Code = 500
		loginResMes.Error = "该用户不存在"
	}*/

	//到redis数据库中完成验证
	user, err := model.MyUserDao.Login(loginMes.UserId, loginMes.UserPwd)
	if err != nil {
		if err == model.ERROR_USER_NOTEXISTS {
			loginResMes.Code = 500
			loginResMes.Error = err.Error()
		}else if err == model.ERROT_USER_PWD {
			loginResMes.Code = 400
			loginResMes.Error = err.Error()
		}else {
			loginResMes.Code = 505
			loginResMes.Error = "服务器内部错误"
		}
	}else {
		loginResMes.Code = 200
		//更新id
		this.UserId = loginMes.UserId
		//因为用户已经登陆成功，把登陆成功的用户放入到userMgr中
		userMgr.AddOnlineUser(this)
		this.NotifyOtherOnlineUser(loginMes.UserId)
		//将当前在线用户的id 放入到loginResMer.UserId这个全局变量中
		for id,_ := range userMgr.onlineUsers{
			loginResMes.UsersId = append(loginResMes.UsersId, id)
		}
		fmt.Println(user, "登陆成功！")
	}

	//将 loginResMes序列化
	data, err := json.Marshal(loginResMes)
	if err != nil {
		fmt.Println("119json.Marshal err=", err)
		return
	}

	//将data赋值给resMes
	resMes.Data = string(data)

	//resMes 进行序列化，准备发送
	data, err = json.Marshal(resMes)
	if err != nil {
		fmt.Println("129json.Marsha fail=", err)
		return
	}

	//发送数据
	tf := &utils.Transfer{
		Conn: this.Conn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("201 ServerProcessLogin err", err)
		return
	}
	return
}

